package com.starxg.m3u8.utils;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 普通异步操作的线程池
 * 
 * @author huangxingguang@lvmama.com
 * @date 2020-06-01 11:41
 */
public class ThreadPoolUtils {
    private static ThreadPoolExecutor pool;
    private static ScheduledThreadPoolExecutor schedulePool;

    public static void execute(Runnable runnable) {
        initPool().execute(runnable);
    }

    public static void execute(Runnable runnable, long delay, TimeUnit timeUnit) {
        initSchedulePool().schedule(runnable, delay, timeUnit);
    }

    public static ScheduledFuture<?> submit(Runnable runnable, long delay, TimeUnit timeUnit) {
        return initSchedulePool().schedule(runnable, delay, timeUnit);
    }

    public static ScheduledFuture<?> submit(Runnable runnable, long initialDelay, long delay, TimeUnit timeUnit) {
        return initSchedulePool().scheduleWithFixedDelay(runnable, initialDelay, delay, timeUnit);
    }

    public static Future<?> submit(Runnable runnable) {
        return initPool().submit(runnable);
    }

    public static <T> Future<T> submit(Callable<T> callable) {
        return initPool().submit(callable);
    }

    public static void close() {

        if (schedulePool != null) {
            schedulePool.shutdownNow();
        }

        if (pool != null) {
            pool.shutdownNow();
        }
    }

    private static ThreadPoolExecutor initPool() {
        if (pool == null) {
            synchronized (ThreadPoolUtils.class) {
                if (pool == null) {
                    pool = new ThreadPoolExecutor(3, 10, 1, TimeUnit.MINUTES, new SynchronousQueue<>(),
                            new ThreadFactory() {
                                private final AtomicInteger integer = new AtomicInteger();

                                @Override
                                public Thread newThread(Runnable r) {
                                    Thread thread = new Thread(r, "bytebuff-pool-" + integer.incrementAndGet());
                                    thread.setDaemon(true);
                                    return thread;
                                }
                            });
                }
            }
        }
        return pool;
    }

    private static ScheduledThreadPoolExecutor initSchedulePool() {
        if (schedulePool == null) {
            synchronized (ThreadPoolUtils.class) {
                if (schedulePool == null) {
                    schedulePool = new ScheduledThreadPoolExecutor(10, new ThreadFactory() {
                        private final AtomicInteger integer = new AtomicInteger();

                        @Override
                        public Thread newThread(Runnable r) {
                            Thread thread = new Thread(r, "bytebuff-scheduled-pool-" + integer.incrementAndGet());
                            thread.setDaemon(true);
                            return thread;
                        }
                    });
                }
            }
        }
        return schedulePool;
    }
}
